package com.crud.generator.generator;

import com.crud.generator.model.EntityMetadata;
import com.crud.generator.model.TableMetadata;
import com.crud.generator.model.ColumnMetadata;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * CRUD 代码生成器
 * 
 * @author CRUD-Generator
 */
@Component
@Slf4j
public class CrudGenerator {
    
    @Value("${generator.output-path}")
    private String outputPath;
    
    @Value("${generator.package-prefix}")
    private String packagePrefix;
    
    @Value("${generator.author}")
    private String author;

    private static final String DEFAULT_CACHE_SUFFIX = "Cache";
    private static final String DEFAULT_SECURITY_ROLE = "ROLE_ADMIN";
    private static final String DEFAULT_SECURITY_TENANT = "tenant-master";
    private static final String DEFAULT_SECURITY_USERNAME = "admin";
    private static final String DEFAULT_SECURITY_PASSWORD = "Admin@123";
    private static final String DEFAULT_SECURITY_TOKEN_HEADER = "Authorization";
    private static final String DEFAULT_SECURITY_TOKEN_PREFIX = "Bearer ";
    private static final String DEFAULT_SECURITY_TENANT_HEADER = "X-Tenant-Id";
    private static final long DEFAULT_JWT_EXPIRATION_SECONDS = 3600L;
    private static final long DEFAULT_JWT_REFRESH_EXPIRATION_SECONDS = 2592000L;
    
    private final Configuration freemarkerConfig;
    
    public CrudGenerator() {
        this.freemarkerConfig = new Configuration(Configuration.VERSION_2_3_32);
        this.freemarkerConfig.setClassForTemplateLoading(this.getClass(), "/templates");
        this.freemarkerConfig.setDefaultEncoding("UTF-8");
        // 使用标准的插值语法，支持更好的模板兼容性
        this.freemarkerConfig.setInterpolationSyntax(Configuration.DOLLAR_INTERPOLATION_SYNTAX);
        // 设置数字格式，避免科学计数法显示
        this.freemarkerConfig.setNumberFormat("0.##########");
        // 设置布尔值格式
        this.freemarkerConfig.setBooleanFormat("true,false");
        // 禁用模板缓存，确保修改立即生效（开发环境）
        this.freemarkerConfig.setTemplateUpdateDelayMilliseconds(0);
        // 设置缓存存储为空，完全禁用缓存
        this.freemarkerConfig.setCacheStorage(new freemarker.cache.NullCacheStorage());
    }
    
    /**
     * 设置输出路径
     */
    public void setOutputPath(String outputPath) {
        this.outputPath = outputPath;
    }
    
    /**
     * 生成所有代码文件
     */
    public void generateAll(TableMetadata tableMetadata) {
        generateAll(tableMetadata, GenerationOptions.defaults());
    }

    public void generateAll(TableMetadata tableMetadata, GenerationOptions options) {
        GenerationOptions effectiveOptions = options != null ? options : GenerationOptions.defaults();
        EntityMetadata entityMetadata = buildEntityMetadata(tableMetadata, effectiveOptions);
        
        try {
            // 生成Java代码文件
            generateEntity(entityMetadata);
            generateMapper(entityMetadata);
            generateService(entityMetadata);
            generateController(entityMetadata);
            generateApplication(entityMetadata);

            if (entityMetadata.isEnableSecurity()) {
                generateAuthController(entityMetadata);
                generateSecurityConfig(entityMetadata);
                generateTenantSecurityProperties(entityMetadata);
                generateJwtAuthenticationEntryPoint(entityMetadata);
                generateJwtAuthenticationFilter(entityMetadata);
                generateJwtTokenProvider(entityMetadata);
                generateTenantAuthenticationService(entityMetadata);
                generateMybatisTenantConfig(entityMetadata);
                generateTenantContext(entityMetadata);
                generateTenantFilter(entityMetadata);
                generateTenantLineHandler(entityMetadata);
            }

            if (entityMetadata.isEnableRedis()) {
                generateRedisConfig(entityMetadata);
            }
            
            // 生成项目配置文件
            generatePom(entityMetadata);
            generateApplicationYml(entityMetadata);
            generateReadme(entityMetadata);
            
            // 生成前端配置文件
            generateFrontendEntities(entityMetadata);
            generateFrontendPackage(entityMetadata);
            generateFrontendReadme(entityMetadata);
            generateFrontendViteConfig(entityMetadata);
            generateFrontendEnv(entityMetadata);
            generateFrontendGitignore(entityMetadata);
            generateFrontendTsConfig(entityMetadata);
            generateFrontendTsNodeConfig(entityMetadata);
            generateFrontendESLintConfig(entityMetadata);
            generateFrontendIndexHtml(entityMetadata);
            
            // 生成前端核心文件
            generateFrontendMain(entityMetadata);
            generateFrontendApp(entityMetadata);
            generateFrontendRouter(entityMetadata);
            generateFrontendApiBase(entityMetadata);
            generateFrontendApiRequest(entityMetadata);
            generateFrontendTypesApi(entityMetadata);
            generateFrontendTypesEntity(entityMetadata);
            generateFrontendStylesIndex(entityMetadata);
            generateFrontendUtilsFormat(entityMetadata);
            generateFrontendViewsDashboard(entityMetadata);
            generateFrontendViewsEntity(entityMetadata);
            generateFrontendComponentsEntityManager(entityMetadata);

            if (entityMetadata.isEnableSecurity()) {
                generateFrontendApiAuth(entityMetadata);
                generateFrontendStoreAuth(entityMetadata);
                generateFrontendViewsLogin(entityMetadata);
            }
            
            log.info("代码生成完成: {}", entityMetadata.getClassName());
        } catch (Exception e) {
            log.error("代码生成失败", e);
            throw new RuntimeException("代码生成失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 预览所有代码内容
     */
    public Map<String, String> previewAll(TableMetadata tableMetadata) {
        return previewAll(tableMetadata, GenerationOptions.defaults());
    }

    public Map<String, String> previewAll(TableMetadata tableMetadata, GenerationOptions options) {
        GenerationOptions effectiveOptions = options != null ? options : GenerationOptions.defaults();
        EntityMetadata entityMetadata = buildEntityMetadata(tableMetadata, effectiveOptions);
        Map<String, String> codePreview = new HashMap<>();
        
        try {
            // Java代码文件
            codePreview.put("entity", previewEntity(entityMetadata));
            codePreview.put("repository", previewMapper(entityMetadata));
            codePreview.put("service", previewService(entityMetadata));
            codePreview.put("controller", previewController(entityMetadata));
            codePreview.put("application", previewApplication(entityMetadata));
            
            // 项目配置文件
            codePreview.put("pom", previewPom(entityMetadata));
            codePreview.put("applicationYml", previewApplicationYml(entityMetadata));
            codePreview.put("readme", previewReadme(entityMetadata));
            
            // 前端配置文件
            codePreview.put("frontendEntities", previewFrontendEntities(entityMetadata));
            codePreview.put("frontendPackage", previewFrontendPackage(entityMetadata));
            codePreview.put("frontendReadme", previewFrontendReadme(entityMetadata));
            codePreview.put("frontendMain", previewFrontendMain(entityMetadata));
            codePreview.put("frontendApp", previewFrontendApp(entityMetadata));
            codePreview.put("frontendRouter", previewFrontendRouter(entityMetadata));
            codePreview.put("frontendApiBase", previewFrontendApiBase(entityMetadata));
            codePreview.put("frontendApiRequest", previewFrontendApiRequest(entityMetadata));
            codePreview.put("frontendTypesApi", previewFrontendTypesApi(entityMetadata));
            codePreview.put("frontendTypesEntity", previewFrontendTypesEntity(entityMetadata));
            codePreview.put("frontendStylesIndex", previewFrontendStylesIndex(entityMetadata));
            codePreview.put("frontendUtilsFormat", previewFrontendUtilsFormat(entityMetadata));
            codePreview.put("frontendViewDashboard", previewFrontendViewsDashboard(entityMetadata));
            codePreview.put("frontendViewEntity", previewFrontendViewsEntity(entityMetadata));
            codePreview.put("frontendComponentEntityManager", previewFrontendComponentsEntityManager(entityMetadata));

            if (entityMetadata.isEnableSecurity()) {
                codePreview.put("authController", previewAuthController(entityMetadata));
                codePreview.put("securityConfig", previewSecurityConfig(entityMetadata));
                codePreview.put("tenantSecurityProperties", previewTenantSecurityProperties(entityMetadata));
                codePreview.put("jwtAuthenticationEntryPoint", previewJwtAuthenticationEntryPoint(entityMetadata));
                codePreview.put("jwtAuthenticationFilter", previewJwtAuthenticationFilter(entityMetadata));
                codePreview.put("jwtTokenProvider", previewJwtTokenProvider(entityMetadata));
                codePreview.put("tenantAuthenticationService", previewTenantAuthenticationService(entityMetadata));
                codePreview.put("mybatisTenantConfig", previewMybatisTenantConfig(entityMetadata));
                codePreview.put("tenantContext", previewTenantContext(entityMetadata));
                codePreview.put("tenantFilter", previewTenantFilter(entityMetadata));
                codePreview.put("tenantLineHandler", previewTenantLineHandler(entityMetadata));
                codePreview.put("frontendApiAuth", previewFrontendApiAuth(entityMetadata));
                codePreview.put("frontendViewLogin", previewFrontendViewsLogin(entityMetadata));
                codePreview.put("frontendStoreAuth", previewFrontendStoreAuth(entityMetadata));
            }

            if (entityMetadata.isEnableRedis()) {
                codePreview.put("redisConfig", previewRedisConfig(entityMetadata));
            }

            log.info("代码预览生成完成: {}", entityMetadata.getClassName());
            return codePreview;
        } catch (Exception e) {
            log.error("代码预览失败", e);
            throw new RuntimeException("代码预览失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 预览实体类代码
     */
    public String previewEntity(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/entity.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 预览Mapper代码
     */
    public String previewMapper(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/repository.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 预览Service代码
     */
    public String previewService(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/service.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 预览Controller代码
     */
    public String previewController(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/controller.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 预览启动类代码
     */
    public String previewApplication(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/config/application-main.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 预览pom.xml
     */
    public String previewPom(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/config/pom.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 预览application.yml
     */
    public String previewApplicationYml(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/config/application.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 预览README.md
     */
    public String previewReadme(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        dataModel.put("originalSql", getOriginalSql(entityMetadata.getTableMetadata()));
        Template template = freemarkerConfig.getTemplate("code-templates/config/readme.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewRedisConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/config/RedisConfig.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewSecurityConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/config/SecurityConfig.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewTenantSecurityProperties(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/config/TenantSecurityProperties.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewJwtAuthenticationEntryPoint(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/security/JwtAuthenticationEntryPoint.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewJwtAuthenticationFilter(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/security/JwtAuthenticationFilter.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewJwtTokenProvider(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/security/JwtTokenProvider.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewTenantAuthenticationService(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/security/TenantAuthenticationService.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewMybatisTenantConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/config/MybatisTenantConfig.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewTenantContext(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/tenant/TenantContext.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewTenantFilter(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/tenant/TenantFilter.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewTenantLineHandler(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/tenant/TenantLineHandlerImpl.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewAuthController(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/controller/AuthController.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 生成实体类
     */
    public void generateEntity(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/java/entity.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getEntityFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成实体类: {}", filePath);
    }
    
    /**
     * 生成 Mapper
     */
    public void generateMapper(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/java/repository.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getMapperFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成Mapper: {}", filePath);
    }
    
    /**
     * 生成 Service
     */
    public void generateService(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/java/service.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getServiceFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成Service: {}", filePath);
    }
    
    /**
     * 生成 Controller
     */
    public void generateController(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/java/controller.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getControllerFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成Controller: {}", filePath);
    }
    
    /**
     * 生成启动类
     */
    public void generateApplication(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/config/application-main.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getApplicationFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成启动类: {}", filePath);
    }
    
    /**
     * 生成pom.xml
     */
    public void generatePom(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/config/pom.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getPomFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成pom.xml: {}", filePath);
    }
    
    /**
     * 生成application.yml
     */
    public void generateApplicationYml(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/config/application.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getApplicationYmlFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成application.yml: {}", filePath);
    }
    
    /**
     * 生成README.md
     */
    public void generateReadme(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        // 添加原始SQL到数据模型中
        dataModel.put("originalSql", getOriginalSql(entityMetadata.getTableMetadata()));
        
        Template template = freemarkerConfig.getTemplate("code-templates/config/readme.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getReadmeFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成README.md: {}", filePath);
    }

    public void generateRedisConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/config/RedisConfig.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getConfigFilePath(entityMetadata, "RedisConfig");
        writeToFile(filePath, content);
        log.info("生成RedisConfig.java: {}", filePath);
    }

    public void generateSecurityConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/config/SecurityConfig.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getConfigFilePath(entityMetadata, "SecurityConfig");
        writeToFile(filePath, content);
        log.info("生成SecurityConfig.java: {}", filePath);
    }

    public void generateTenantSecurityProperties(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/config/TenantSecurityProperties.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getConfigFilePath(entityMetadata, "TenantSecurityProperties");
        writeToFile(filePath, content);
        log.info("生成TenantSecurityProperties.java: {}", filePath);
    }

    public void generateJwtAuthenticationEntryPoint(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/security/JwtAuthenticationEntryPoint.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getSecurityFilePath(entityMetadata, "JwtAuthenticationEntryPoint");
        writeToFile(filePath, content);
        log.info("生成JwtAuthenticationEntryPoint.java: {}", filePath);
    }

    public void generateJwtAuthenticationFilter(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/security/JwtAuthenticationFilter.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getSecurityFilePath(entityMetadata, "JwtAuthenticationFilter");
        writeToFile(filePath, content);
        log.info("生成JwtAuthenticationFilter.java: {}", filePath);
    }

    public void generateJwtTokenProvider(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/security/JwtTokenProvider.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getSecurityFilePath(entityMetadata, "JwtTokenProvider");
        writeToFile(filePath, content);
        log.info("生成JwtTokenProvider.java: {}", filePath);
    }

    public void generateTenantAuthenticationService(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/security/TenantAuthenticationService.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getSecurityFilePath(entityMetadata, "TenantAuthenticationService");
        writeToFile(filePath, content);
        log.info("生成TenantAuthenticationService.java: {}", filePath);
    }

    public void generateMybatisTenantConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/config/MybatisTenantConfig.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getConfigFilePath(entityMetadata, "MybatisTenantConfig");
        writeToFile(filePath, content);
        log.info("生成MybatisTenantConfig.java: {}", filePath);
    }

    public void generateTenantContext(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/tenant/TenantContext.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getTenantFilePath(entityMetadata, "TenantContext");
        writeToFile(filePath, content);
        log.info("生成TenantContext.java: {}", filePath);
    }

    public void generateTenantFilter(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/tenant/TenantFilter.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getTenantFilePath(entityMetadata, "TenantFilter");
        writeToFile(filePath, content);
        log.info("生成TenantFilter.java: {}", filePath);
    }

    public void generateTenantLineHandler(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/tenant/TenantLineHandlerImpl.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getTenantFilePath(entityMetadata, "TenantLineHandlerImpl");
        writeToFile(filePath, content);
        log.info("生成TenantLineHandlerImpl.java: {}", filePath);
    }

    public void generateAuthController(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/java/controller/AuthController.ftl");
        String content = processTemplate(template, dataModel);
        String filePath = getControllerFilePath(entityMetadata, "AuthController");
        writeToFile(filePath, content);
        log.info("生成AuthController.java: {}", filePath);
    }
    
    /**
     * 构建实体元数据
     */
    private EntityMetadata buildEntityMetadata(TableMetadata tableMetadata) {
        return buildEntityMetadata(tableMetadata, GenerationOptions.defaults());
    }

    private EntityMetadata buildEntityMetadata(TableMetadata tableMetadata, GenerationOptions options) {
        String className = toPascalCase(tableMetadata.getTableName());
        GenerationOptions effectiveOptions = options != null ? options : GenerationOptions.defaults();
        boolean enableSecurity = effectiveOptions.isEnableSecurity();
        boolean enableRedis = effectiveOptions.isEnableRedis();
        String cacheName = enableRedis ? className + DEFAULT_CACHE_SUFFIX : "";
        String jwtSecret = enableSecurity ? UUID.randomUUID().toString().replace("-", "") : "";
        
        return EntityMetadata.builder()
            .className(className)
            .packageName(packagePrefix)
            .tableMetadata(tableMetadata)
            .author(author)
            .enableSecurity(enableSecurity)
            .enableRedis(enableRedis)
            .cacheName(cacheName)
            .securityRole(DEFAULT_SECURITY_ROLE)
            .securityDefaultTenant(DEFAULT_SECURITY_TENANT)
            .securityDefaultUsername(DEFAULT_SECURITY_USERNAME)
            .securityDefaultPassword(DEFAULT_SECURITY_PASSWORD)
            .securityTokenHeader(DEFAULT_SECURITY_TOKEN_HEADER)
            .securityTokenPrefix(DEFAULT_SECURITY_TOKEN_PREFIX)
            .securityTenantHeader(DEFAULT_SECURITY_TENANT_HEADER)
            .jwtSecret(jwtSecret)
            .jwtExpirationSeconds(DEFAULT_JWT_EXPIRATION_SECONDS)
            .jwtRefreshExpirationSeconds(DEFAULT_JWT_REFRESH_EXPIRATION_SECONDS)
            .build();
    }
    
    /**
     * 构建数据模型
     */
    private Map<String, Object> buildDataModel(EntityMetadata entityMetadata) {
        Map<String, Object> dataModel = new HashMap<>();
        TableMetadata table = entityMetadata.getTableMetadata();
        
        dataModel.put("packageName", entityMetadata.getPackageName());
        dataModel.put("className", entityMetadata.getClassName());
        dataModel.put("lowerClassName", entityMetadata.getLowerClassName());
        dataModel.put("author", entityMetadata.getAuthor());
        dataModel.put("tableName", table.getTableName());
        dataModel.put("tableComment", table.getTableComment());
        dataModel.put("columns", table.getColumns());
        dataModel.put("enableRedis", entityMetadata.isEnableRedis());
        dataModel.put("enableSecurity", entityMetadata.isEnableSecurity());
        dataModel.put("cacheName", entityMetadata.getCacheName());

        if (entityMetadata.isEnableSecurity()) {
            dataModel.put("securityRole", entityMetadata.getSecurityRole());
            dataModel.put("securityDefaultTenant", entityMetadata.getSecurityDefaultTenant());
            dataModel.put("securityDefaultUsername", entityMetadata.getSecurityDefaultUsername());
            dataModel.put("securityDefaultPassword", entityMetadata.getSecurityDefaultPassword());
            dataModel.put("securityTokenHeader", entityMetadata.getSecurityTokenHeader());
            dataModel.put("securityTokenPrefix", entityMetadata.getSecurityTokenPrefix());
            dataModel.put("securityTenantHeader", entityMetadata.getSecurityTenantHeader());
            dataModel.put("jwtSecret", entityMetadata.getJwtSecret());
            dataModel.put("jwtExpirationSeconds", entityMetadata.getJwtExpirationSeconds());
            dataModel.put("jwtRefreshExpirationSeconds", entityMetadata.getJwtRefreshExpirationSeconds());
        }
        
        // 主键相关信息
        if (table.getPrimaryKey() != null) {
            ColumnMetadata pk = table.getPrimaryKey();
            dataModel.put("primaryKeyField", pk.getJavaFieldName());
            dataModel.put("primaryKeyProperty", pk.getJavaPropertyName());
            dataModel.put("primaryKeyType", pk.getJavaType());
            dataModel.put("primaryKeyColumn", pk.getColumnName());
            dataModel.put("hasSinglePrimaryKey", !table.isCompositePrimaryKey());
            dataModel.put("hasCompositePrimaryKey", table.isCompositePrimaryKey());
        } else {
            // 检查是否为复合主键表（没有单一主键但有多个字段）
            boolean hasCompositePrimaryKey = table.getColumns().stream()
                .anyMatch(col -> Boolean.TRUE.equals(col.getPrimaryKey()));
            
            if (hasCompositePrimaryKey) {
                // 复合主键情况，使用第一个主键字段作为代表
                ColumnMetadata firstPk = table.getColumns().stream()
                    .filter(col -> Boolean.TRUE.equals(col.getPrimaryKey()))
                    .findFirst()
                    .orElse(null);
                
                if (firstPk != null) {
                    dataModel.put("primaryKeyField", firstPk.getJavaFieldName());
                    dataModel.put("primaryKeyProperty", firstPk.getJavaPropertyName());
                    dataModel.put("primaryKeyType", firstPk.getJavaType());
                    dataModel.put("primaryKeyColumn", firstPk.getColumnName());
                    dataModel.put("hasSinglePrimaryKey", false);
                    dataModel.put("hasCompositePrimaryKey", true);
                } else {
                    // 提供默认值避免模板报错
                    dataModel.put("primaryKeyField", "id");
                    dataModel.put("primaryKeyProperty", "Id");
                    dataModel.put("primaryKeyType", "Long");
                    dataModel.put("primaryKeyColumn", "id");
                    dataModel.put("hasSinglePrimaryKey", false);
                    dataModel.put("hasCompositePrimaryKey", false);
                }
            } else {
                // 提供默认值避免模板报错
                dataModel.put("primaryKeyField", "id");
                dataModel.put("primaryKeyProperty", "Id");
                dataModel.put("primaryKeyType", "Long");
                dataModel.put("primaryKeyColumn", "id");
                dataModel.put("hasSinglePrimaryKey", false);
                dataModel.put("hasCompositePrimaryKey", false);
            }
        }
        
        // 检查是否包含特定类型
        dataModel.put("hasDateType", hasDateType(table.getColumns()));
        dataModel.put("hasBigDecimal", hasBigDecimalType(table.getColumns()));
        
        return dataModel;
    }
    
    /**
     * 处理模板
     */
    private String processTemplate(Template template, Map<String, Object> dataModel) throws Exception {
        StringWriter writer = new StringWriter();
        template.process(dataModel, writer);
        return writer.toString();
    }
    
    /**
     * 写入文件
     */
    private void writeToFile(String filePath, String content) throws Exception {
        File file = new File(filePath);
        file.getParentFile().mkdirs();
        
        try (FileWriter writer = new FileWriter(file, false)) {
            writer.write(content);
        }
    }
    
    /**
     * 获取实体类文件路径
     */
    private String getEntityFilePath(EntityMetadata entityMetadata) {
        return String.format("%s/%s/entity/%s.java", 
            outputPath,
            entityMetadata.getPackageName().replace(".", "/"),
            entityMetadata.getClassName()
        );
    }
    
    /**
     * 获取Mapper文件路径
     */
    private String getMapperFilePath(EntityMetadata entityMetadata) {
        return String.format("%s/%s/mapper/%sMapper.java", 
            outputPath,
            entityMetadata.getPackageName().replace(".", "/"),
            entityMetadata.getClassName()
        );
    }
    
    /**
     * 获取Service文件路径
     */
    private String getServiceFilePath(EntityMetadata entityMetadata) {
        return String.format("%s/%s/service/%sService.java", 
            outputPath,
            entityMetadata.getPackageName().replace(".", "/"),
            entityMetadata.getClassName()
        );
    }
    
    /**
     * 获取Controller文件路径
     */
    private String getControllerFilePath(EntityMetadata entityMetadata) {
        return getControllerFilePath(entityMetadata, entityMetadata.getClassName() + "Controller");
    }

    private String getControllerFilePath(EntityMetadata entityMetadata, String controllerName) {
        return String.format("%s/%s/controller/%s.java",
            outputPath,
            entityMetadata.getPackageName().replace(".", "/"),
            controllerName
        );
    }
    
    /**
     * 获取启动类文件路径
     */
    private String getApplicationFilePath(EntityMetadata entityMetadata) {
        return String.format("%s/%s/%sApplication.java", 
            outputPath,
            entityMetadata.getPackageName().replace(".", "/"),
            entityMetadata.getClassName()
        );
    }
    
    /**
     * 获取pom.xml文件路径
     */
    private String getPomFilePath(EntityMetadata entityMetadata) {
        return String.format("%s/pom.xml", outputPath);
    }
    
    /**
     * 获取application.yml文件路径
     */
    private String getApplicationYmlFilePath(EntityMetadata entityMetadata) {
        return String.format("%s/src/main/resources/application.yml", outputPath);
    }
    
    /**
     * 获取README.md文件路径
     */
    private String getReadmeFilePath(EntityMetadata entityMetadata) {
        return String.format("%s/README.md", outputPath);
    }

    private String getConfigFilePath(EntityMetadata entityMetadata, String className) {
        return String.format("%s/%s/config/%s.java",
            outputPath,
            entityMetadata.getPackageName().replace(".", "/"),
            className
        );
    }

    private String getSecurityFilePath(EntityMetadata entityMetadata, String className) {
        return String.format("%s/%s/security/%s.java",
            outputPath,
            entityMetadata.getPackageName().replace(".", "/"),
            className
        );
    }

    private String getTenantFilePath(EntityMetadata entityMetadata, String className) {
        return String.format("%s/%s/tenant/%s.java",
            outputPath,
            entityMetadata.getPackageName().replace(".", "/"),
            className
        );
    }

    /**
     * 预览前端实体配置文件
     */
    public String previewFrontendEntities(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildFrontendDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/entities.ftl");
        return processTemplate(template, dataModel);
    }

    /**
     * 生成前端实体配置文件
     */
    public void generateFrontendEntities(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildFrontendDataModel(entityMetadata);

        Template template = freemarkerConfig.getTemplate("code-templates/frontend/entities.ftl");
        String content = processTemplate(template, dataModel);

        String filePath = getFrontendEntitiesFilePath(entityMetadata);
        writeToFile(filePath, content);

        log.info("生成前端实体配置: {}", filePath);
    }

    /**
     * 构建前端数据模型
     */
    private Map<String, Object> buildFrontendDataModel(EntityMetadata entityMetadata) {
        Map<String, Object> dataModel = new HashMap<>();
        TableMetadata table = entityMetadata.getTableMetadata();

        dataModel.put("packageName", entityMetadata.getPackageName());
        dataModel.put("className", entityMetadata.getClassName());
        dataModel.put("lowerClassName", entityMetadata.getLowerClassName());
        dataModel.put("author", entityMetadata.getAuthor());
        dataModel.put("tableName", table.getTableName());
        dataModel.put("tableComment", table.getTableComment());
        dataModel.put("tables", buildFrontendTablesData(table));

        return dataModel;
    }

    /**
     * 构建前端表数据结构
     */
    private java.util.List<Map<String, Object>> buildFrontendTablesData(TableMetadata table) {
        java.util.List<Map<String, Object>> tables = new java.util.ArrayList<>();
        Map<String, Object> tableData = new HashMap<>();

        tableData.put("className", toPascalCase(table.getTableName()));
        tableData.put("tableName", table.getTableName());
        tableData.put("displayName", table.getTableComment() != null ? table.getTableComment() : toPascalCase(table.getTableName()));
        tableData.put("comment", table.getTableComment());
        tableData.put("hasCompositePrimaryKey", table.isCompositePrimaryKey());

        java.util.List<Map<String, Object>> columns = new java.util.ArrayList<>();
        for (ColumnMetadata column : table.getColumns()) {
            Map<String, Object> columnData = new HashMap<>();
            columnData.put("javaFieldName", column.getJavaFieldName());
            columnData.put("columnName", column.getColumnName());
            columnData.put("javaType", column.getJavaType());
            columnData.put("comment", column.getColumnComment());
            columnData.put("nullable", column.getNullable());
            columnData.put("primaryKey", column.getPrimaryKey());
            columnData.put("autoIncrement", column.getAutoIncrement());
            columnData.put("stringType", "String".equals(column.getJavaType()));
            columnData.put("textType", column.getDataType() != null &&
                (column.getDataType().toLowerCase().contains("text") ||
                 column.getDataType().toLowerCase().contains("varchar")));
            columnData.put("dateType", column.getJavaType() != null &&
                (column.getJavaType().contains("Date") || column.getJavaType().contains("Time")));
            columnData.put("numberType", column.getJavaType() != null &&
                (column.getJavaType().equals("Integer") ||
                 column.getJavaType().equals("Long") ||
                 column.getJavaType().equals("Double") ||
                 column.getJavaType().equals("BigDecimal")));
            columnData.put("decimalType", "BigDecimal".equals(column.getJavaType()));
            columnData.put("largeTextType", column.getDataType() != null &&
                (column.getDataType().toLowerCase().contains("text") ||
                 (column.getLength() != null && column.getLength() > 255)));
            columnData.put("length", column.getLength());
            columnData.put("scale", column.getScale());
            columnData.put("defaultValue", column.getDefaultValue());
            columns.add(columnData);
        }

        tableData.put("columns", columns);
        tables.add(tableData);

        return tables;
    }

    /**
     * 获取前端实体配置文件路径
     */
    private String getFrontendEntitiesFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + "src" + File.separator +
               "config" + File.separator + "entities.ts";
    }
    
    /**
     * 预览前端package.json
     */
    public String previewFrontendPackage(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/package.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 生成前端package.json
     */
    public void generateFrontendPackage(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/package.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendPackageFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端package.json: {}", filePath);
    }
    
    /**
     * 预览前端README.md
     */
    public String previewFrontendReadme(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        dataModel.put("originalSql", getOriginalSql(entityMetadata.getTableMetadata()));
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/readme.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendMain(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/main.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendApp(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/app.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendRouter(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/router.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendApiBase(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/api-base.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendApiRequest(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/api-request.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendApiAuth(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/api-auth.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendTypesApi(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/types-api.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendTypesEntity(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/types-entity.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendStylesIndex(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/styles-index.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendUtilsFormat(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/utils-format.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendViewsDashboard(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/views-dashboard.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendViewsEntity(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/views-entity.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendViewsLogin(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/views-login.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendComponentsEntityManager(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/components-entity-manager.ftl");
        return processTemplate(template, dataModel);
    }

    public String previewFrontendStoreAuth(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/stores-auth.ftl");
        return processTemplate(template, dataModel);
    }
    
    /**
     * 生成前端README.md
     */
    public void generateFrontendReadme(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        dataModel.put("originalSql", getOriginalSql(entityMetadata.getTableMetadata()));
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/readme.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendReadmeFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端README.md: {}", filePath);
    }
    
    /**
     * 获取前端package.json文件路径
     */
    private String getFrontendPackageFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + "package.json";
    }
    
    /**
     * 获取前端README.md文件路径
     */
    private String getFrontendReadmeFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + "README.md";
    }
    
    /**
     * 生成前端Vite配置文件
     */
    public void generateFrontendViteConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/vite-config.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendViteConfigFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端Vite配置: {}", filePath);
    }
    
    /**
     * 生成前端环境变量文件
     */
    public void generateFrontendEnv(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/env.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendEnvFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端环境变量: {}", filePath);
    }
    
    /**
     * 生成前端.gitignore文件
     */
    public void generateFrontendGitignore(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/gitignore.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendGitignoreFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端.gitignore: {}", filePath);
    }
    
    /**
     * 获取前端Vite配置文件路径
     */
    private String getFrontendViteConfigFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + "vite.config.ts";
    }
    
    /**
     * 获取前端环境变量文件路径
     */
    private String getFrontendEnvFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + ".env";
    }
    
    /**
     * 获取前端.gitignore文件路径
     */
    private String getFrontendGitignoreFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + ".gitignore";
    }
    
    /**
     * 生成前端TypeScript配置文件
     */
    public void generateFrontendTsConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/tsconfig.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendTsConfigFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端TypeScript配置: {}", filePath);
    }
    
    /**
     * 生成前端TypeScript节点配置文件
     */
    public void generateFrontendTsNodeConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/tsconfig-node.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendTsNodeConfigFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端TypeScript节点配置: {}", filePath);
    }
    
    /**
     * 获取前端TypeScript配置文件路径
     */
    private String getFrontendTsConfigFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + "tsconfig.json";
    }
    
    /**
     * 获取前端TypeScript节点配置文件路径
     */
    private String getFrontendTsNodeConfigFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + "tsconfig.node.json";
    }
    
    /**
     * 生成前端ESLint配置文件
     */
    public void generateFrontendESLintConfig(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/eslint.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendESLintFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端ESLint配置: {}", filePath);
    }
    
    /**
     * 生成前端Index HTML文件
     */
    public void generateFrontendIndexHtml(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/index-html.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = getFrontendIndexHtmlFilePath(entityMetadata);
        writeToFile(filePath, content);
        
        log.info("生成前端Index HTML: {}", filePath);
    }
    
    /**
     * 获取前端ESLint配置文件路径
     */
    private String getFrontendESLintFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + ".eslintrc.cjs";
    }
    
    /**
     * 获取前端Index HTML文件路径
     */
    private String getFrontendIndexHtmlFilePath(EntityMetadata entityMetadata) {
        return outputPath + File.separator + entityMetadata.getLowerClassName() +
               File.separator + "frontend" + File.separator + "index.html";
    }
    
    /**
     * 获取原始SQL（用于README文档）
     */
    private String getOriginalSql(TableMetadata tableMetadata) {
        // 这里可以根据表元数据重构建表SQL，或者从其他地方获取
        // 暂时返回一个示例
        StringBuilder sql = new StringBuilder();
        sql.append("CREATE TABLE ").append(tableMetadata.getTableName()).append(" (\n");
        
        for (int i = 0; i < tableMetadata.getColumns().size(); i++) {
            ColumnMetadata column = tableMetadata.getColumns().get(i);
            sql.append("    ").append(column.getColumnName())
               .append(" ").append(column.getDataType());
            
            if (column.getLength() != null) {
                sql.append("(").append(column.getLength());
                if (column.getScale() != null) {
                    sql.append(",").append(column.getScale());
                }
                sql.append(")");
            }
            
            if (column.getPrimaryKey()) {
                sql.append(" PRIMARY KEY");
            }
            
            if (column.getAutoIncrement()) {
                sql.append(" AUTO_INCREMENT");
            }
            
            if (!column.getNullable()) {
                sql.append(" NOT NULL");
            }
            
            if (column.getDefaultValue() != null) {
                sql.append(" DEFAULT '").append(column.getDefaultValue()).append("'");
            }
            
            if (column.getColumnComment() != null) {
                sql.append(" COMMENT '").append(column.getColumnComment()).append("'");
            }
            
            if (i < tableMetadata.getColumns().size() - 1) {
                sql.append(",");
            }
            sql.append("\n");
        }
        
        sql.append(")");
        
        if (tableMetadata.getTableComment() != null) {
            sql.append(" COMMENT '").append(tableMetadata.getTableComment()).append("'");
        }
        
        sql.append(";");
        
        return sql.toString();
    }
    
    /**
     * 转换为PascalCase
     */
    private String toPascalCase(String str) {
        if (StringUtils.isBlank(str)) {
            return str;
        }
        
        StringBuilder result = new StringBuilder();
        boolean toUpper = true;
        
        for (char c : str.toCharArray()) {
            if (c == '_') {
                toUpper = true;
            } else {
                if (toUpper) {
                    result.append(Character.toUpperCase(c));
                    toUpper = false;
                } else {
                    result.append(Character.toLowerCase(c));
                }
            }
        }
        
        return result.toString();
    }
    
    /**
     * 检查是否包含日期时间类型
     */
    private boolean hasDateType(java.util.List<ColumnMetadata> columns) {
        return columns.stream()
            .anyMatch(col -> col.getJavaType().startsWith("Local"));
    }
    
    /**
     * 检查是否包含BigDecimal类型
     */
    private boolean hasBigDecimalType(java.util.List<ColumnMetadata> columns) {
        return columns.stream()
            .anyMatch(col -> "BigDecimal".equals(col.getJavaType()));
    }
    
    // ==================== 新增前端核心文件生成方法 ====================
    
    /**
     * 生成前端main.ts文件
     */
    public void generateFrontendMain(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/main.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + "main.ts";
        writeToFile(filePath, content);
        
        log.info("生成前端main.ts: {}", filePath);
    }
    
    /**
     * 生成前端App.vue文件
     */
    public void generateFrontendApp(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/app.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + "App.vue";
        writeToFile(filePath, content);
        
        log.info("生成前端App.vue: {}", filePath);
    }
    
    /**
     * 生成前端router/index.ts文件
     */
    public void generateFrontendRouter(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/router.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "router" + File.separator + "index.ts";
        writeToFile(filePath, content);
        
        log.info("生成前端router/index.ts: {}", filePath);
    }
    
    /**
     * 生成前端api/base.ts文件
     */
    public void generateFrontendApiBase(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/api-base.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "api" + File.separator + "base.ts";
        writeToFile(filePath, content);
        
        log.info("生成前端api/base.ts: {}", filePath);
    }
    
    /**
     * 生成前端api/request.ts文件
     */
    public void generateFrontendApiRequest(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/api-request.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "api" + File.separator + "request.ts";
        writeToFile(filePath, content);
        
        log.info("生成前端api/request.ts: {}", filePath);
    }
    
    /**
     * 生成前端types/api.ts文件
     */
    public void generateFrontendTypesApi(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/types-api.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "types" + File.separator + "api.ts";
        writeToFile(filePath, content);
        
        log.info("生成前端types/api.ts: {}", filePath);
    }
    
    /**
     * 生成前端types/entity.ts文件
     */
    public void generateFrontendTypesEntity(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/types-entity.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "types" + File.separator + "entity.ts";
        writeToFile(filePath, content);
        
        log.info("生成前端types/entity.ts: {}", filePath);
    }
    
    /**
     * 生成前端styles/index.css文件
     */
    public void generateFrontendStylesIndex(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/styles-index.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "styles" + File.separator + "index.css";
        writeToFile(filePath, content);
        
        log.info("生成前端styles/index.css: {}", filePath);
    }
    
    /**
     * 生成前端utils/formatUtils.ts文件
     */
    public void generateFrontendUtilsFormat(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/utils-format.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "utils" + File.separator + "formatUtils.ts";
        writeToFile(filePath, content);
        
        log.info("生成前端utils/formatUtils.ts: {}", filePath);
    }
    
    /**
     * 生成前端views/Dashboard.vue文件
     */
    public void generateFrontendViewsDashboard(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/views-dashboard.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "views" + File.separator + "Dashboard.vue";
        writeToFile(filePath, content);
        
        log.info("生成前端views/Dashboard.vue: {}", filePath);
    }
    
    /**
     * 生成前端views/EntityView.vue文件
     */
    public void generateFrontendViewsEntity(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/views-entity.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "views" + File.separator + "EntityView.vue";
        writeToFile(filePath, content);
        
        log.info("生成前端views/EntityView.vue: {}", filePath);
    }
    
    /**
     * 生成前端components/EntityManager.vue文件
     */
    public void generateFrontendComponentsEntityManager(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);
        
        Template template = freemarkerConfig.getTemplate("code-templates/frontend/components-entity-manager.ftl");
        String content = processTemplate(template, dataModel);
        
        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator + 
                         "components" + File.separator + "EntityManager.vue";
        writeToFile(filePath, content);
        
        log.info("生成前端components/EntityManager.vue: {}", filePath);
    }

    /**
     * 生成前端api/auth.ts文件
     */
    public void generateFrontendApiAuth(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);

        Template template = freemarkerConfig.getTemplate("code-templates/frontend/api-auth.ftl");
        String content = processTemplate(template, dataModel);

        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator +
                         "api" + File.separator + "auth.ts";
        writeToFile(filePath, content);

        log.info("生成前端api/auth.ts: {}", filePath);
    }

    /**
     * 生成前端stores/auth.ts文件
     */
    public void generateFrontendStoreAuth(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);

        Template template = freemarkerConfig.getTemplate("code-templates/frontend/stores-auth.ftl");
        String content = processTemplate(template, dataModel);

        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator +
                         "stores" + File.separator + "auth.ts";
        writeToFile(filePath, content);

        log.info("生成前端stores/auth.ts: {}", filePath);
    }

    /**
     * 生成前端views/LoginView.vue文件
     */
    public void generateFrontendViewsLogin(EntityMetadata entityMetadata) throws Exception {
        Map<String, Object> dataModel = buildDataModel(entityMetadata);

        Template template = freemarkerConfig.getTemplate("code-templates/frontend/views-login.ftl");
        String content = processTemplate(template, dataModel);

        String filePath = outputPath + File.separator + entityMetadata.getLowerClassName() +
                         File.separator + "frontend" + File.separator + "src" + File.separator +
                         "views" + File.separator + "LoginView.vue";
        writeToFile(filePath, content);

        log.info("生成前端views/LoginView.vue: {}", filePath);
    }
}
